package smallfrench.moteur.biblio;

import java.util.Iterator;
import java.util.NoSuchElementException;

import smallfrench.moteur.interp.RObjet;

/**
 * Un itérateur abstrait.
 * @author antoine1023
 */
public abstract class AIterateur extends AIterable {

	public static final AClasse CLASSE = AClasse.creer(
			AIterateur.class, "Iterateur");

	@AnnotationMembre
	public AIterateur() {
	}

	@Override
	@AnnotationMembre
	public RChaine enChaine() {
		return new RChaine("Iterateur");
	}

	/**
	 * 
	 * @return L’objet suivant de l’itérateur.
	 */
	@AnnotationMembre
	public abstract RObjet suivant();

	/**
	 * @return <code>vrai</code> si l’itérateur contient d’autres objets.
	 */
	@AnnotationMembre
	public abstract RBooleen contientAutres();


	/**
	 * @return this
	 */
	@Override
	@AnnotationMembre
	public AIterateur iterateur() {
		return this;
	}

	/**
	 * Une implémentation de {@link AIterateur} basée sur {@link Iterator}.
	 * @author antoine1023
	 */
	public static class AIterateurStandard extends AIterateur {

		public static final AClasse CLASSE = AClasse.creer(
				AIterateurStandard.class, "IterateurStandard");

		private Iterator<RObjet> iterator;

		@AnnotationMembre
		public AIterateurStandard(Iterator<RObjet> iterator) {
			this.iterator = iterator;
		}

		@Override
		@AnnotationMembre
		public RObjet suivant() {
			try {
				return iterator.next();
			} catch (NoSuchElementException e) {
				return null;
			}
		}

		@Override
		@AnnotationMembre
		public RBooleen contientAutres() {
			return RBooleen.nouveau(iterator.hasNext());
		}
	}
}
